package cate.game.play.buff;

import cate.common.table.d.GDBuff;
import cate.game.play.config.buff.BuffCfg;
import cate.game.play.fighter.Fighter;
import cate.game.play.proce.action.ctx.ActionCtx;
import cate.game.play.proce.result.BuffRemoveResult;
import cate.game.play.proce.result.BuffUpdateResult;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.springframework.data.annotation.Transient;

@NoteClass("buff对象")
public class Buff {

	@NoteField("临时id")
	public int pid;

	@NoteField("buff的模板ID")
	public int tid;

	@NoteField("Buff的拥有者")
	@JsonIgnore
	@Transient
	public transient Fighter owner;

	@NoteField("Buff的释放者")
	@JsonIgnore
	@Transient
	public transient Fighter caster;

	@NoteField("添加的回合")
	@JsonProperty("ra")
	public int roundAdd;

	@NoteField("需要移除的回合")
	@JsonProperty("rr")
	public Integer roundRemove;

	@NoteField("buff配置")
	@JsonIgnore
	@Transient
	public transient BuffCfg cfg;

	@NoteField(value = "buff处理器")
	@JsonIgnore
	@Transient
	public transient BuffHandler handler;

	@NoteField("是否有效")
	@JsonIgnore
	@Transient
	public boolean valid = true;

	public Buff() {
	}

	public Buff ownerSet(Fighter owner) {
		this.owner = owner;
		return this;
	}

	public Buff casterSet(Fighter caster) {
		this.caster = caster;
		return this;
	}

	public Buff roundAddSet(int roundAdd) {
		this.roundAdd = roundAdd;
		return this;
	}

	public Buff cfgSet(BuffCfg cfg) {
		this.cfg = cfg;
		this.tid = cfg.id;
		return this;
	}

	public void handlerSet(BuffHandler handler) {
		handler.buff = this;
		this.handler = handler;
	}

	public void setPid(int pid) {
		this.pid = pid;
	}

	/** 被加上时候 */
	public void onAdd(ActionCtx action) {
		this.owner.attr.addAttr(cfg.getExAttr(), true, action);
		this.handler.onAdd(action);
	}

	private void onInvalid(ActionCtx action, byte invalidReason) {
		this.owner.attr.addAttr(cfg.getExAttr(), false, action);
		this.handler.onInvalid(action, invalidReason);
		this.owner.skill.forHandlers(h -> h.onOwnerBuffInvalid(action, invalidReason, this));
		this.caster.skill.forHandlers(h -> h.onCastBuffInvalid(action, invalidReason, this));
//		action.getPlay().teamVS.forFighters(f -> {
//					f.skill.forHandlers(h -> h.onBuffInvalid(action, invalidReason, this));
//					f.buff.forHandlers(h -> h.onBuffInvalid(action, invalidReason, this));
//				}
//		);
	}

	/**
	 * 判断死亡是否可以添加
	 * @return
	 */
	public boolean addable() {
		if (!cfg.row.deadAddable && owner.isDead()) {
			return false;
		}
		return true;
	}

	/**
	 * 是否是控制类buff
	 * @return
	 */
	@JsonIgnore
	public boolean isCtrl(){
		return GDBuff.Type.isCtrl(this.cfg.row.effectType);
	}

	@JsonIgnore
	public boolean isGood(){return this.cfg.row.good;}

	/** 计算结束回合 */
	public void calcRoundRemove() {
		int lastRound = cfg.getLastRound();
		if (lastRound > 0) {
			this.roundRemove = lastRound + roundAdd;
		}
	}

	/** 更新当前回合 */
	public void updateCurRoundIndex(ActionCtx action, byte phase) {
		if (roundRemove != null) {
			if (phase == GDBuff.Phase.ROUND_BEG || phase == GDBuff.Phase.ROUND_IN) {
				if (action.getRound().index >= roundRemove) {
					markInvalid(action, GDBuff.InvalidReason.EXPIRED);
				}
			} else if (phase == GDBuff.Phase.ROUND_END) {
				if (action.getRound().index + 1 >= roundRemove) {
					markInvalid(action, GDBuff.InvalidReason.EXPIRED);
				}
			}
		}
	}

	public void addLastRound(ActionCtx action, int round) {
		if (roundRemove == null) {
			return;
		}
		roundRemove += round;
		action.addResult(new BuffUpdateResult().buffSet(this));
	}


	public void markInvalid(ActionCtx action){
		markInvalid(action, GDBuff.InvalidReason.EXHAUSTED);
	}

	public void markInvalid(ActionCtx action, byte invalidReason) {
		if (this.valid) {
			this.valid = false;
			this.onInvalid(action, invalidReason);
			if (this.cfg.row.notice) {
				action.addResult(new BuffRemoveResult().pidSet(this.owner).buffPidSet(this.pid).buffTidSet(this.tid));
			}
		}
	}

	public void readFrom(Buff tar) {
		this.cfg = tar.cfg;
		this.tid = tar.tid;
		this.pid = tar.pid;
		this.roundAdd = tar.roundAdd;
		this.roundRemove = tar.roundRemove;
	}


	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("◆");
		sb.append("pid=" + pid + " ");
		sb.append("{tid=" + tid + "}");
		sb.append("{name=" + cfg.row.name + "}");
		sb.append("{roundAdd=" + roundAdd+ "}");
		sb.append("{roundRemove=" + roundRemove+ "}");
		sb.append("◆");
		return sb.toString();
	}

}
